﻿// <copyright file="IGameProvider.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains the IGameProvider Interface</summary>

namespace Sqwarea.Persistence
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;

    /// <summary>
    /// Game Provider Interface
    /// </summary>
    public interface IGameProvider : ISquareProvider
    {
        // Getting functions

        /// <summary>
        /// Gets the next King Id.
        /// WARNING : Mock implementation is very different from real one.
        /// </summary>
        /// <returns>Next king Id</returns>
        long GetNextKingId();

        /// <summary>
        /// Get the object king corresponding to the kingId
        /// </summary>
        /// <param name="kingId">Id of the required king</param>
        /// <returns>See summary</returns>
        King GetKingById(long kingId);

        /// <summary>
        /// Get all the squares in a given rectangle
        /// </summary>
        /// <param name="rectangle">Rectangle delimiting the area required</param>
        /// <returns>See summary</returns>
        Square[,] GetSquaresInRectangle(Rectangle rectangle);

        /// <summary>
        /// Get the square at point and the surrondings ones, which has the same partition key
        /// </summary>
        /// <param name="point">Point that must be retrieved</param>
        /// <returns>An IEnumerable containing all square surronding point</returns>
        IEnumerable<Square> GetSquaresInPartition(Point point);

        /// <summary>
        /// Gets all squares of the map
        /// Only used by ConnexityTotalChecker.
        /// NEVER USE IT FOR ANYTHING ELSE !
        /// </summary>
        /// <returns>All squares of the map</returns>
        IEnumerable<Square> GetAllSquares();

        /// <summary>
        /// Gets the incoming attacks to kingId user (i.e. attacks against this king's squares).
        /// </summary>
        /// <param name="kingId">Id of the required king</param>
        /// <returns>See summary</returns>
        IEnumerable<Attack> GetIncomingAttacks(long kingId);

        /// <summary>
        /// Gets the ongoing attacks og kingId user (i.e. attacks sended by this king).
        /// </summary>
        /// <param name="kingId">Id of the required king</param>
        /// <returns>See summary</returns>
        IEnumerable<Attack> GetOngoingAttacks(long kingId);

        // Setting functions

        /// <summary>
        /// Update the information on the square defined by its internal position
        /// </summary>
        /// <param name="square">Square to update (containing position)</param>
        void UpdateSquare(Square square);

        /// <summary>
        /// Update the information on the squares given in the IEnumerable
        /// </summary>
        /// <param name="squares">Squares to update (containing position)</param>
        void UpdateSquares(IEnumerable<Square> squares);

        /// <summary>
        /// Atomic update of a Square
        /// </summary>
        /// <param name="position">The position of the square to update</param>
        /// <param name="updateFunction">Function that must be called on the square</param>
        /// <returns>the updated Square</returns>
        Square UpdateSquare(Point position, Func<Square, Square> updateFunction);

        /// <summary>
        /// Update the information on an existing king (defined by its id) or create a new king if the id is
        /// not referenced
        /// </summary>
        /// <param name="king">King to create or update (containing id)</param>
        void UpdateKing(King king);

        /// <summary>
        /// Atomic update of a King
        /// </summary>
        /// <param name="kingId">Id of king to update</param>
        /// <param name="updateFunction">Function that must be called on the king</param>
        /// <returns>the updated King</returns>
        King UpdateKing(long kingId, Func<King, King> updateFunction);

        /// <summary>
        /// Returns an IEnumerable that contains all kings. For everyday top kings sorting
        /// </summary>
        /// <returns>An object from which we can get all kings.</returns>
        IEnumerable<King> GetAllKings();

        /// <summary>
        /// Create a new attack
        /// </summary>
        /// <param name="attack">Attack to create</param>
        void NewAttack(Attack attack);

        /// <summary>
        /// Deletes all ellapsed attack on all specifed kingIds
        /// </summary>
        /// <param name="kingIds">Kings that must be "cleaned"</param>
        void ClearElapsedAttacks(IEnumerable<long> kingIds);
    }
}
